#! /usr/bin/python

# +------------------------------+
# |         LED电灯程序          |
# | GPIO2 接按键 | GPIO3  接LED灯|
# | 功能说明：                   |
# | 按键切换LED灯状态。          |
# +------------------------------+

# Coded by Qi

####! 使用GPIO模块需要的工作 ####
# +-----------------------------+
# 引入GPIO模块
import RPi.GPIO as GPIO
from time import time

# 指定GPIO的编码方式, 这里使用BCM编码方式。
# 具体信息参考 https://pinout.xyz/pinout/5v_power
GPIO.setmode(GPIO.BCM)

# (非必需)关闭警告信息
GPIO.setwarnings(False)

####! 变量定义 ####
# +-----------------------------+
# "=" 表示赋值。用法： 变量名 = 数值
# 选择需要控制的GPIO引脚
# button引引脚，按键一边接GPIO2，一边接5v。
btn_pin = 1

# led引脚接LED灯的正极, 另一个引脚接地线(GND)。
led_r = 2
led_g = 3
led_b = 4

####! 初始化所使用的GPIO ####
# +-----------------------------+
# 因为要控制LED灯，所以led_pin设置为输出模式
GPIO.setup(led_r, GPIO.OUT)  # 输出模式
GPIO.setup(led_g, GPIO.OUT)  # 输出模式
GPIO.setup(led_b, GPIO.OUT)  # 输出模式

# 检测按键的状态，当按键引脚的状态发生改变时，该改变灯的状态。
GPIO.setup(btn_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # 输入模式, 并设置下拉

# 先设置LED灯的状态为灭
GPIO.output(led_r, GPIO.LOW)
GPIO.output(led_g, GPIO.LOW)
GPIO.output(led_b, GPIO.LOW)

INTRERVAL = 1 # 变化间隔



def breath():
    T = 0  # 循环量 0 - 600
    led_id = 0 # 灯的id
    btn_time = time() # 设置按键间隔
    step = INTRERVAL
    p = [GPIO.PWM(led_r, 100), GPIO.PWM(led_g, 100),GPIO.PWM(led_b, 100)]
    for i in range(3): p[i].start(T)
    while 1:
        if step > 0: # 判断状态（开启时step > 0, 反之小于零）
            T += step 
            if T == 600: T = 0 # 实现循环
            led_id = T // 200 # 计算控制的灯
            bright = 100 - abs(100-T % 200) # 计算亮度
            p[led_id].ChangeDutyCycle(bright) # 改变灯的亮度
        res = GPIO.wait_for_edge(btn_pin, GPIO.RISING, timeout=10) # 灯变化间隔时间
        now = time()
        if res!= None and now - btn_time > 0.5: # 按键间隔时间大于0.5s
            btn_time = now

            # 简化写法（不推荐）
            for i in range(3): p[i].ChangeDutyCycle(0) # 关闭所有灯
            step = (not step) * INTRERVAL

            # 正常写法
            # if step > 0:
            #     step = 0
            #     for i in range(3): p[i].ChangeDutyCycle(0) # 关闭所有灯
            # else:
            #     step = INTRERVAL
breath()
